#ifndef __DATABASE_STD_SQL_RUN_EVENT_HPP__
#define __DATABASE_STD_SQL_RUN_EVENT_HPP__

#ifdef ENABLE_DB_JUDGE

#include "base_event.hpp"

namespace run_code_event_space {

struct database_std_sql_run_event : base_event<database_std_sql_run_event> {
    template <class U>
    ProcessStatus execute_impl(run_code_context_t<U>& context, const string& inFile);
};


template <class U>
ProcessStatus database_std_sql_run_event::execute_impl(run_code_context_t<U>& context, const string& inFile) {
    if constexpr (contains_v<U, DatabaseModifyJudge, DatabaseSelectJudge>) {
        const U& judge_type = context.judge_type;
        const RuncodeParams& params = context. params;
        int mode = std::is_same_v<U, DatabaseSelectJudge> ? DATABASE_SELECT_JUDGE : DATABASE_MODIFY_JUDGE;
        std::string outFile = inFile.substr(0, inFile.size() - 2) + "stdout";
        auto& [stdLang, stdCodeFile, stdBinFile, stdCompileStr, stdRunStr] = judge_type.stdCodeInfo;
        auto res = general_execution_strategy::check_and_update(judge_type.stdFile, stdCodeFile, 
            [src = judge_type.stdFile, dst = stdCodeFile]() {
                auto res = langMap["default"]->prepare(src, dst);
                if (res == "") {
                    return ProcessStatus{.result = SYS_ERROR, .error = "copy std file error"};
                }
                return ProcessStatus{.result = RUN_OK};
        });

        if (res.result != RUN_OK) {
            return res;
        }

        outFile = langMap["default"]->detect(outFile, params.spjCachePath);
        return general_execution_strategy::run_sql<false>(&context.judge_type.conn, context.judge_type.database_name, judge_type.stdCodeInfo.codeFile, mode, inFile, outFile, params.timeLimit, params.memoryLimit);
    }
    return ProcessStatus{ .result = RUN_FAIL, .error = "no support"};
}

}

#endif

#endif /* __DATABASE_STD_SQL_RUN_EVENT_HPP__ */
